package com.xiweicheng.test.springboot.ldap;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

public class LDAPUtil {

	/**
	 * 此方法为验证Ldap服务器中是否有该角色(用户名密码是否正确)
	 * @param adminName :username@domain 
	 * @param adminPassword :password
	 * @param ldapURL :ip:port
	 * @return 返回“IsHava”则有该用户  返回“NotHava”则无该用户
	 */
	public static boolean IsHave(String adminName, String adminPassword, String ldapURL) {
		Properties env = new Properties();
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
		env.put(Context.SECURITY_AUTHENTICATION, "simple"); //"none","simple","strong"  
		env.put(Context.SECURITY_PRINCIPAL, adminName);
		env.put(Context.SECURITY_CREDENTIALS, adminPassword);
		env.put(Context.PROVIDER_URL, ldapURL);
		try {
			LdapContext ctx = new InitialLdapContext(env, null);
		} catch (NamingException e) {
			e.printStackTrace();
			System.out.println("用户名密码或链接有误");
			return false;
		}

		return true;
	}

	/**
	 * 此方法为获取Ldap的连接
	 * @param adminName :username@domain 
	 * @param adminPassword :password
	 * @param ldapURL :ip:port
	 * @param Authentication :"none","simple","strong"  
	 * @return 返回连接对象
	 */
	public static LdapContext GetConnect(String adminName, String adminPassword, String ldapURL,
			String authentication) {
		Properties env = new Properties();
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
		env.put(Context.SECURITY_AUTHENTICATION, authentication);
		env.put(Context.SECURITY_PRINCIPAL, adminName);
		env.put(Context.SECURITY_CREDENTIALS, adminPassword);
		env.put(Context.PROVIDER_URL, ldapURL);
		LdapContext ctx = null;
		try {
			ctx = new InitialLdapContext(env, null);
		} catch (NamingException e) {
			e.printStackTrace();
			System.out.println("参数有误，获取Ldap连接失败");
			return null;
		}

		return ctx;
	}

	/**
	 * 此方法为查询特定条件下的属性信息
	 * @param LdapContext :传入连接对象
	 * @param searchFilter :过滤条件
	 * @param searchBase :指定层级目录，从指定目录下查询
	 * @param returnedAtts :查询的属性
	 * @return 返回list即为结果
	 */
	public static Map<String, String> LdapSearch(LdapContext ctx, String searchFilter, String searchBase,
			String[] returnedAtts) {
		Map<String, String> map = new HashMap<String, String>();
		try {
			SearchControls searchCtls = new SearchControls();
			searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
			searchCtls.setReturningAttributes(returnedAtts);
			NamingEnumeration<SearchResult> answer = ctx.search(searchBase, searchFilter, searchCtls);
			while (answer.hasMoreElements()) {
				SearchResult sr = (SearchResult) answer.next();
				NamingEnumeration<? extends Attribute> attrs = sr.getAttributes().getAll();
				while (attrs.hasMore()) {
					Attribute attr = attrs.next();
					map.put(attr.getID(), (String) attr.get());
				}
			}
			ctx.close();
		} catch (NamingException e) {
			e.printStackTrace();
			System.err.println("Problem searching directory: " + e);
			System.out.println("查询有误，请检查参数");
			return null;
		}

		return map;
	}
}